const crypto = require('crypto');
const urllib = require('urllib');

// 基础post请求方法
// @param  config   配置项 包含AppId、AppSecret、Gateway
// @param  url   接口连接
// @param  data  请求数据
//          例如 {
//          "user_id":"1",
//          "app_key":"242896740640882688",
//          "nonce_str":"00MfDabo23zhjXUmBXPSBZYmVGPkqC",
//          "time_stamp":1623389353,
//       }
// @param  callbackFunc 回调函数
exports.request = function (config, url, data, callbackFunc) {
    data['app_key'] = config.AppId;
    data['time_stamp'] = exports.getTimestamp();
    data['nonce_str'] = exports.getNonceStr();
    data['sign'] = exports.sign(data, config.AppSecret);

    var headers = {
        'Content-Type': 'application/json',
    };
    urllib.request(config.Gateway + url, {
        method: 'POST',
        headers: headers,
        data: data,
        dataType: 'json'
    }, callbackFunc);
};

// 构建标准的字段排序签名数据
// @param  data     待签名数据
//          例如 {
//          "user_id":"1",
//          "app_key":"242896740640882688",
//          "nonce_str":"00MfDabo23zhjXUmBXPSBZYmVGPkqC",
//          "time_stamp":1623389353,
//       }
// @param  secret   应用秘钥
// @return signed  签名数据
exports.sign = function (data, secret) {
    var keys = Object.keys(data).sort(), str = '';
    for (var key of keys) {
        if (key == 'sign' || (!data[key] && data[key] !== 0)) {
            continue;
        }
        str += `${key}=${data[key]}&`;
    }
    str += `app_secret=${secret}`;
    var md5 = crypto.createHash('md5');
    var toSignStr = md5.update(str).digest('hex');
    return toSignStr.toUpperCase();
};

// 产秒级时间戳
// @return string 产生的随机字符串
exports.getTimestamp = function () {
    return parseInt(Date.now() / 1000);
};

// 产生随机字符串，不长于32位
// @param  length     待验签数据
// @return string 产生的随机字符串
exports.getNonceStr = function (length = 32) {
    var $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
    var $arr = [];
    for (var i = 0; i < length; i++) {
        $arr.push($chars.charAt(parseInt(Math.random() * length)));
    }
    return $arr.join('');
};

// 验签
// @param  data     待验签数据
//    例如 {
//         "user_id":"1",
//         "task_id":218,
//         "type":2,
//         "app_key":"242896740640882688",
//         "nonce_str":"00MfDabo23zhjXUmBXPSBZYmVGPkqC",
//         "time_stamp":1623389353,
//         "sign":"95960A3B04A97B6BFAAE05C2F817A36A"
//     }
// @param  secret   应用秘钥
// @return bool  true 验签成功 ，异常为签名错误
exports.verifySign = function (data, secret) {
    var signStr = data['sign'];
    if (!signStr) {
        throw new Error('签名错误');
    }

    if (exports.sign(data, secret) === signStr) {
        //签名正确
        return true;
    }
    throw new Error('签名错误');
};

module.exports = exports;
